<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>High_order_function</title>
</head>
<body>

</body>
<script>
         function add (x,y,z){
             return x+y+z;
         }

         x = -5;
         y = 6;
         f = Math.abs;
         z=f(x) + f (y);
         console.log(z);

         function add (x,y,f){
              return f(x) + f(y);
         }

         let x = add(-5,6,Math.abs);
         console.log(x);

         function pow(x){
             return x * x;
             console.log("函数能指向函数");
         }

         let arr  = [1,2,3,4,5,6,7,8,9,10];
         let result = arr.map(pow);
         console.log(result);
         console.log(arr.map(String));     // 调用string 函数

        let arr = [1,2,3,4,5,6,7,8,9,10];
        arr.reduce(function(x,y){
            return x+y;
        });

        //     reduce   求积
         function product(arr){
               function multiply(x,y){
                   return x*y;
               }
               return arr.reduce(multiply);
         }
         if (product([1,2,3,4])===24&&product([0,1,2]) === 0 && product([99,88,77,66]) === 44274384){
             console.log("测试通过");
         }
         else{
             console.log("测试失败!");
         }

         let arr = [1,3,5,7,9];
         arr.reduce(function (x,y){
             return x *10 +y;
         });


         //   parseInt  测试
         function string2int(str){
              let arr = str.split();

              let numArr = arr.map(char => char - '0');

              return numArr.reduce((acc,current)=>acc * 10 + current,0);
         }

         if(string2int('0') === 0 && string2int('123') === 123 && string2int('-12') === -12){
             if(string2int.toString().indexOf('parseInt') !== -1){
                    console.log('请勿使用parseInt()!');
             }else if(string2int.toString().indexOf('Number') !== -1){
                 console.log('请勿使用Number()!');
             }else{
                 console.log('测试通过!');
             }
         }
         else{
             console.log('测试失败!');
         }

         // 测试 首字母大写,其余小写
         function normalize(arr){
             return arr.map(function (x){
                 return x.charAt(0).toUpperCase() + x.slice(1).toLowerCase();
             });
         }
         if(normalize(['hello', 'world']) === ['Hello', 'World']){
             console.log('测试通过!');
         }
         else{
             console.log('测试失败!');
         }


         let arr = [1,2,3,4,5,6,7,8,9,10];
         let r = arr.filter(
             function (x){
                 return x % 2 === 0;
             }
         );

         let arr_1 = ['A', 'B', 'C', 'D',null, undefined,' '];
         let r_1 = arr_1.filter(
             function (s){
                 return s && s.trim();
             }
         );

         let arr = ['A','B','C','D'];
         let m  = arr.filter(
             function (element,index,self){
                 console.log(element);
                 console.log(index);
                 console.log(self);
                 return true;
             }
         );

         //  去重
         let arr_2 = ['apple','orange','apple','pear','orange'];
         let r_2 = arr_2.filter(function (element,index,self){
             return self.indexOf(element) === index;
         });
          console.log(r_2);

          //  筛选素数
         let arr = [1,2,3,4,5,6,7,8,9,10];
         let r = arr.filter(function (x){
             for(let i = 2;i < x;i++){
                 if(x % i === 0){
                     return false;
                 }
             }
             return true;
         });
         console.log(r);

         //  sort 测试

         let arr = [1,2,3,4,5,6,7,8,9,10];

         arr.sort(function(x,y){
              if(x<y){
                  return -1;
              }
              else (x>y)
             {
                  return 1;
             }
              return 0;
         });
         console.log(arr);

         let arr_String = ['Google','Rob','Taobao'];
         arr_String.sort(function (s1,s2){
               x1 = s1.toUpperCase();
               x2 = s2.toUpperCase();
               if(x1 < x2){
                   return -1;
               }
               else if(x1 > x2){
                   return 1;
               }
               else {
                   return 0;
               };
         });

         let a1 = ['A','C','B'];
         let a2 = a1.sort();
         console.log(a1);
         console.log(a2);
         if (a1 === a2){
             console.log('测试通过!');
         }
         else{
             console.log('测试失败!');
         }

         //  every  some 测试
         let arr = ['apple','pear','orange'];
         console.log(arr.every(function(s){
                return s.length >0;
         }));
         console.log(arr.some(function(s){
                return s.toLowerCase() === s;
         }));
         console.log(arr.some(function(s){
                return s.toUpperCase() === s;
         }));

         //  find 测试
         let arr = ['Apple','pear','orange'];
         console.log(arr.find(function(s){
             return s.toLowerCase() === s;
         }));
         console.log(arr.find(function(s){
             return s.toUpperCase() === s;
         }));
         console.log(arr.find(function(s){
             return s.length > 0;
         }));

         // finddIndex 测试   返回索引

         let arr = ['Apple','pear','orange'];
         console.log(arr.findIndex(function(s){
             return s.toLowerCase() === s;
         }));
         console.log(arr.findIndex(function(s){
             return s.toUpperCase() === s;
         }));

         // foreach
         let arr = ['Apple','pear','orange'];
         arr.forEach(function(s){
             console.log(s);
         });

         //  闭包
         function sum(arr){
             return arr.reduce(function(x,y){
                 return x + y;
             });
         }
         sum([1,2,3,4]);

         function lazy_sum(arr){
             let sum = function(){
                 return arr.reduce(function(x,y){
                     return x + y;
                 });
             }
             return sum;
         }
         let f = lazy_sum([1,2,3,4]);


         function count(){
             let arr = [];
             for(var i=1; i<3 ;I++){
                 arr.push(function(){
                     return i*i;

                 });
             }
             return arr;
         }
         let results = count();
         let [f1,f2,f3] = results;


         function count(){
             let arr = [];
             let i;
             for(i=1; i<3 ;i++){
                 arr.push(function(){
                     return i*i;
                 });
             }
             return arr;
         }

         function create_counter(initial){
             let x = initial || 0;
             return {
                 inc: function (){
                     x +=1;
                     return x;
                 }
             }
         }

        function make_pow( n){
             return function (x){
                 return Math.pow(x,n);
             }
        }

        //  创建两个函数
         let pow2 = make_pow(2);
         let pow3 = make_pow(3);

         console.log(pow2(5));
         console.log(pow3(5));

         console.log(pow2(4));
         console.log(pow3(4));

         // this  箭头函数的 this 是定义时的 this ，而不是执行时 this
         let obj = {
             birth:1990,
             getAge:function(){
                 let b = this.birth;
                 let fn = () =>new Date().getFullYear() - this.birth;
                 return fn();
             }
         };
         obj.getAge();

         // 箭头练习
         let arr = [10,20,1,2];
         arr.sort((x,y)=>y-x);
         console.log(arr);

         let name = 'x';
         let age = 18;
         let s = `你好,${name},你今年${age}岁！`;
         console.log(s)

         const email = "test@example.com";
         const password = "123456";

         function sql(strings, ...exps){
             console.log(`SQl:${string.join('?')}`);
             console.log(`SQL parameters:${JSON.stringify(exps)}`);
             return {
                 name: 'x',
                 age: 18
             };
         }
        const result = sql`SELECT * FROM users WHERE email=${email} AND password=${password}`;
        console.log(JSON.stringify(result)) ;

        let id = 123;
        let age = 21;
        let score = 'A';
        update `UPDATE uses SET age =${age},score=${score} WHERE id=${id}`;

        //  斐波那契函数
         function fib(max){
             let t,
                 a=0,
                 b=1,
                 arr=[0,1];
             while (arr.length<max){
                 [a,b] = [b,a+b];
                 arr.push(b);
             }
             return arr;
         }
         fib(10);
         fib(20);

         let fib ={
             a:0,
             b:1,
             n:0,
             max:5,
             next:function(){
                 let r = this.a,
                     t = this.a + this.b;
                 this.a = this.b;
                 this.b =t;
                 if(this.n<this.max){
                     this.n++;
                     return r;
                 }else{
                     return undefined;
                 }
             }
         }




</script>
</html>